home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / symbol.h < prev    next >
C/C++ Source or Header  |  2000-01-16  |  73KB  |  2,326 lines

  1. // $Id: symbol.h,v 1.31 1999/11/18 03:37:23 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef symbol_INCLUDED
  11. #define symbol_INCLUDED
  12.  
  13. #include "config.h"
  14. #include <assert.h>
  15. #include <stddef.h>
  16. #include <stdio.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <string.h>
  20. #include "code.h"
  21. #include "stream.h"
  22. #include "option.h"
  23. #include "lookup.h"
  24. #include "depend.h"
  25. #include "access.h"
  26. #include "tuple.h"
  27. #include "case.h"
  28.  
  29. class Semantic;
  30. class SemanticEnvironment;
  31. class Ast;
  32. class AstCompilationUnit;
  33. class AstMethodDeclarator;
  34. class AstBlock;
  35. class AstList;
  36. class AstExpression;
  37. class AstVariableDeclarator;
  38. class ExpandedTypeTable;
  39. class ExpandedFieldTable;
  40. class ExpandedMethodTable;
  41. class SymbolTable;
  42. class SymbolSet;
  43. class SymbolMap;
  44. class Zip;
  45.  
  46. class PackageSymbol;
  47.  
  48. class PathSymbol : public Symbol
  49. {
  50. public:
  51.     NameSymbol *name_symbol;
  52.     Zip *zipfile;
  53.  
  54.     PathSymbol(NameSymbol *);
  55.     virtual ~PathSymbol();
  56.  
  57.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  58.     virtual size_t NameLength() { return name_symbol -> NameLength(); }
  59.     virtual NameSymbol *Identity() { return name_symbol; }
  60.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  61.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  62.  
  63.     inline bool IsZip() { return zipfile != NULL; }
  64.  
  65.     inline DirectorySymbol *RootDirectory() { return root_directory; }
  66.  
  67. private:
  68.     friend class SymbolTable;
  69.     DirectorySymbol *root_directory;
  70. };
  71.  
  72.  
  73. class DirectorySymbol : public Symbol
  74. {
  75. public:
  76.     Symbol *owner;
  77.     NameSymbol *name_symbol;
  78.  
  79.     Tuple<DirectorySymbol *> subdirectories;
  80.  
  81.     DirectorySymbol(NameSymbol *, Symbol *);
  82.     virtual ~DirectorySymbol();
  83.  
  84.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  85.     virtual size_t NameLength() { return name_symbol -> NameLength(); }
  86.     virtual NameSymbol *Identity() { return name_symbol; }
  87.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  88.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  89.  
  90.     DirectoryEntry *FindEntry(char *name, int len) { return (entries ? entries -> FindEntry(name, len) : (DirectoryEntry *) NULL); }
  91.  
  92. #ifdef WIN32_FILE_SYSTEM
  93.     DirectoryEntry *FindCaseInsensitiveEntry(char *name, int length)
  94.     {
  95.         return (entries ? entries -> FindCaseInsensitiveEntry(name, length) : (DirectoryEntry *) NULL);
  96.     }
  97.  
  98.     void InsertEntry(char *name, int length)
  99.     {
  100.         assert(entries);
  101.  
  102.         DirectoryEntry *entry = entries -> InsertEntry((DirectorySymbol *) this, name, length);
  103.         entries -> InsertCaseInsensitiveEntry(entry);
  104.  
  105.         return;
  106.     }
  107. #endif
  108.  
  109.     PathSymbol *PathSym()
  110.     {
  111.         return (owner -> PathCast() ? (PathSymbol *) owner : ((DirectorySymbol *) owner) -> PathSym());
  112.     }
  113.  
  114.     inline bool IsZip() { return PathSym() -> IsZip(); }
  115.  
  116.     void SetDirectoryName();
  117.     inline char *DirectoryName()
  118.     {
  119.         if (! directory_name)
  120.             SetDirectoryName();
  121.         return directory_name;
  122.     }
  123.     inline size_t DirectoryNameLength()
  124.     {
  125.         if (! directory_name)
  126.             SetDirectoryName();
  127.         return directory_name_length;
  128.     }
  129.  
  130.     inline DirectorySymbol *InsertDirectorySymbol(NameSymbol *);
  131.     inline DirectorySymbol *FindDirectorySymbol(NameSymbol *);
  132.  
  133.     inline FileSymbol *InsertFileSymbol(NameSymbol *);
  134.     inline FileSymbol *FindFileSymbol(NameSymbol *);
  135.  
  136.     void ResetDirectory();
  137.  
  138.     void ReadDirectory();
  139.  
  140. private:
  141.  
  142.     time_t mtime;
  143.  
  144.     SymbolTable *table;
  145.     inline SymbolTable *Table();
  146.  
  147.     DirectoryTable *entries;
  148.     char *directory_name;
  149.     size_t directory_name_length;
  150. };
  151.  
  152.  
  153. class FileSymbol : public Symbol
  154. {
  155. private:
  156.     enum FileKind
  157.     {
  158.         JAVA,
  159.         CLASS,
  160.         CLASS_ONLY
  161.     };
  162.  
  163.     DirectorySymbol *output_directory;
  164.     char *file_name;
  165.     size_t file_name_length;
  166.     Utf8LiteralValue *file_name_literal;
  167.  
  168. public:
  169.     NameSymbol *name_symbol;
  170.     DirectorySymbol *directory_symbol;
  171.     PackageSymbol *package;
  172.     FileKind kind;
  173.  
  174.     //
  175.     // These fields are used for files in zip packages.
  176.     //
  177.     u4 uncompressed_size;
  178.     u4 date_time;
  179.     long offset;
  180.  
  181.     //
  182.     // This field holds the time of last data modification for a non-zip file
  183.     //
  184.     time_t mtime;
  185.  
  186.     //
  187.     // These fields are used for buffer "files".
  188.     //
  189.     char *buffer;
  190.  
  191.     LexStream *lex_stream;
  192.     AstCompilationUnit *compilation_unit;
  193.     Semantic *semantic;
  194.  
  195.     Tuple<TypeSymbol *> types;
  196.  
  197.     FileSymbol(NameSymbol *name_symbol_) : output_directory(NULL),
  198.                                            file_name(NULL),
  199.                                            file_name_literal(NULL),
  200.                                            name_symbol(name_symbol_),
  201.                                            directory_symbol(NULL),
  202.                                            package(NULL),
  203.                                            mtime(0),
  204.                                            buffer(NULL),
  205.                                            lex_stream(NULL),
  206.                                            compilation_unit(NULL),
  207.                                            semantic(NULL),
  208.                                            types(4)
  209.     {
  210.          Symbol::_kind = _FILE;
  211.     }
  212.  
  213.     virtual ~FileSymbol()
  214.     {
  215.         delete [] file_name;
  216.         delete buffer;
  217.         delete lex_stream;
  218.     }
  219.  
  220.     FileSymbol *Clone()
  221.     {
  222.         FileSymbol *clone = new FileSymbol(name_symbol);
  223.  
  224.         clone -> kind = kind;
  225.         clone -> directory_symbol = directory_symbol;
  226.         clone -> mtime = mtime;
  227.  
  228.         return clone;
  229.     }
  230.  
  231.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  232.     virtual size_t NameLength() { return name_symbol -> NameLength(); }
  233.     virtual NameSymbol *Identity() { return name_symbol; }
  234.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  235.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  236.  
  237.     inline void SetJava()       { kind = JAVA; }
  238.     inline void SetClass()      { kind = CLASS; }
  239.     inline void SetClassOnly()  { kind = CLASS_ONLY; }
  240.  
  241.     inline bool IsJava()       { return kind == JAVA; }
  242.     inline bool IsClass()      { return kind >= CLASS; }
  243.     inline bool IsClassOnly()  { return kind == CLASS_ONLY; }
  244.  
  245.     PathSymbol *PathSym()
  246.     {
  247.         return directory_symbol -> PathSym();
  248.     }
  249.     inline bool IsZip() { return PathSym() -> IsZip(); }
  250.     inline Zip *Zipfile() { return PathSym() -> zipfile; }
  251.  
  252.     static char *java_suffix;
  253.     static int java_suffix_length;
  254.     static char *class_suffix;
  255.     static int class_suffix_length;
  256.     static inline bool IsJavaSuffix(char *ptr);
  257.     static inline bool IsClassSuffix(char *ptr);
  258.  
  259.     inline char *FileName()
  260.     {
  261.         if (! file_name)
  262.             SetFileName();
  263.         return file_name;
  264.     }
  265.     inline int FileNameLength()
  266.     {
  267.         if (! file_name)
  268.             SetFileName();
  269.         return file_name_length;
  270.     }
  271.  
  272.     inline Utf8LiteralValue *FileNameLiteral() { assert(file_name_literal); return file_name_literal; }
  273.  
  274.     void SetFileNameLiteral(Control *);
  275.  
  276.     DirectorySymbol *OutputDirectory();
  277.  
  278.     void SetFileName();
  279.  
  280.     void CleanUp();
  281.  
  282.     void Reset()
  283.     {
  284.         CleanUp();
  285.  
  286.         delete [] file_name;
  287.         file_name = NULL;
  288.         types.Reset();
  289.     }
  290. };
  291.  
  292.  
  293. class FileLocation
  294. {
  295. public:
  296.     wchar_t *location;
  297.  
  298.     FileLocation (LexStream *lex_stream, LexStream::TokenIndex token_index)
  299.     {
  300.         char *file_name = lex_stream -> FileName();
  301.         int length = lex_stream -> FileNameLength();
  302.         location = new wchar_t[length + 13];
  303.         for (int i = 0; i < length; i++) {
  304.             location[i] = (wchar_t) file_name[i];
  305.         }
  306.         location[length++] = U_COLON;
  307.  
  308.         IntToWstring line_no(lex_stream -> Line(token_index));
  309.  
  310.         for (int j = 0; j < line_no.Length(); j++)
  311.             location[length++] = line_no.String()[j];
  312.         location[length] = U_NULL;
  313.  
  314.         return;
  315.     }
  316.  
  317.     FileLocation (FileSymbol *file_symbol)
  318.     {
  319.         char *file_name = file_symbol -> FileName();
  320.         int length = file_symbol -> FileNameLength();
  321.         location = new wchar_t[length + 13];
  322.         for (int i = 0; i < length; i++) {
  323.             location[i] = (wchar_t) file_name[i];
  324.         }
  325.         location[length] = U_NULL;
  326.  
  327.         return;
  328.     }
  329.  
  330.     ~FileLocation()
  331.     {
  332.         delete [] location;
  333.     }
  334. };
  335.  
  336.  
  337. class PackageSymbol : public Symbol
  338. {
  339. public:
  340.     Tuple<DirectorySymbol *> directory;
  341.     PackageSymbol *owner;
  342.  
  343.     PackageSymbol(NameSymbol *name_symbol_, PackageSymbol *owner_) : directory(4),
  344.                                                                      owner(owner_),
  345.                                                                      name_symbol(name_symbol_),
  346.                                                                      table(NULL),
  347.                                                                      package_name(NULL)
  348.     {
  349.         Symbol::_kind = PACKAGE;
  350.     }
  351.  
  352.     virtual ~PackageSymbol();
  353.  
  354.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  355.     virtual size_t NameLength() { return name_symbol -> NameLength(); }
  356.     virtual NameSymbol *Identity() { return name_symbol; }
  357.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  358.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  359.     // This name is fully qualified, using slashes.
  360.  
  361.     void SetPackageName();
  362.     // This name is fully qualified, using slashes.
  363.     wchar_t *PackageName()
  364.     {
  365.         if (! package_name)
  366.             SetPackageName();
  367.         return package_name;
  368.     }
  369.     int PackageNameLength()
  370.     {
  371.         if (! package_name)
  372.             SetPackageName();
  373.         return package_name_length;
  374.     }
  375.  
  376.     inline PackageSymbol *FindPackageSymbol(NameSymbol *);
  377.     inline PackageSymbol *InsertPackageSymbol(NameSymbol *);
  378.  
  379.     inline TypeSymbol *FindTypeSymbol(NameSymbol *);
  380.     inline TypeSymbol *InsertSystemTypeSymbol(NameSymbol *);
  381.     inline TypeSymbol *InsertOuterTypeSymbol(NameSymbol *);
  382.     inline void DeleteTypeSymbol(TypeSymbol *);
  383.  
  384. private:
  385.  
  386.     NameSymbol *name_symbol;
  387.     SymbolTable *table;
  388.     inline SymbolTable *Table();
  389.  
  390.     wchar_t *package_name;
  391.     size_t package_name_length;
  392. };
  393.  
  394.  
  395. class MethodSymbol : public Symbol, public AccessFlags
  396. {
  397. public:
  398.     Ast *method_or_constructor_declaration; // AstMethodDeclaration or AstConstructorDeclaration
  399.     NameSymbol *name_symbol;
  400.     TypeSymbol *containing_type;
  401.     BlockSymbol *block_symbol;
  402.     MethodSymbol *next_method;
  403.     Utf8LiteralValue *signature;
  404.  
  405.     //
  406.     // If this method is a method that is generated in order to process initializer
  407.     // blocks contained in the body of a class, it needs to know the set of
  408.     // constructors that might invoke it in order to figure out which exceptions
  409.     // can be safely thrown within an initializer block.
  410.     //
  411.     int NumInitializerConstructors()
  412.     {
  413.         return (initializer_constructors ? initializer_constructors -> Length() : 0);
  414.     }
  415.     MethodSymbol *InitializerConstructor(int i)
  416.     {
  417.         return (*initializer_constructors)[i];
  418.     }
  419.     void AddInitializerConstructor(MethodSymbol *method)
  420.     {
  421.         if (! initializer_constructors)
  422.             initializer_constructors = new Tuple<MethodSymbol *>(8);
  423.         initializer_constructors -> Next() = method;
  424.     }
  425.  
  426.     int max_block_depth;
  427.  
  428.     //
  429.     // If this method is a method that permits access to a private member of an
  430.     // enclosing type then accessed_member identifies the member in question.
  431.     //
  432.     Symbol *accessed_member;
  433.  
  434.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  435.     virtual size_t NameLength() { return name_symbol -> NameLength(); }
  436.     virtual NameSymbol *Identity() { return name_symbol; }
  437.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  438.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  439.  
  440.     MethodSymbol(NameSymbol *name_symbol_) : method_or_constructor_declaration(NULL),
  441.                                              name_symbol(name_symbol_),
  442.                                              containing_type(NULL),
  443.                                              block_symbol(NULL),
  444.                                              next_method(NULL),
  445.                                              signature(NULL),
  446.                                              max_block_depth(1), // there must be at least one block in a method
  447.                                                                  // this default is useful for default constructors.
  448.                                              accessed_member(NULL),
  449.                                              external_name_symbol(NULL),
  450.                                              status(0),
  451.                                              header(NULL),
  452.                                              type_(NULL),
  453.                                              formal_parameters(NULL),
  454.                                              throws(NULL),
  455.                                              throws_signatures(NULL),
  456.                                              initializer_constructors(NULL),
  457.                                              local_constructor(NULL)
  458.     {
  459.         Symbol::_kind = METHOD;
  460.     }
  461.  
  462.     virtual ~MethodSymbol();
  463.  
  464.     bool IsFinal();
  465.  
  466.     bool IsTyped()
  467.     {
  468.         return type_ != NULL;
  469.     }
  470.  
  471.     void SetType(TypeSymbol *_type)
  472.     {
  473.         type_ = _type;
  474.     }
  475.  
  476.     void ProcessMethodSignature(Semantic *, LexStream::TokenIndex);
  477.     void ProcessMethodThrows(Semantic *, LexStream::TokenIndex);
  478.  
  479.     TypeSymbol *Type()
  480.     {
  481.         assert(type_); // make sure that the method signature associated with this method is processed prior to invoking
  482.                        // this function. ( "this -> ProcessMethodSignature(sem, tok);" )
  483.  
  484.         return type_;
  485.     }
  486.  
  487.     int NumFormalParameters()
  488.     {
  489.         assert(type_);
  490.  
  491.         return (formal_parameters ? formal_parameters -> Length() : 0);
  492.     }
  493.     VariableSymbol *FormalParameter(int i)
  494.     {
  495.         return (*formal_parameters)[i];
  496.     }
  497.     void AddFormalParameter(VariableSymbol *variable)
  498.     {
  499.         if (! formal_parameters)
  500.             formal_parameters = new Tuple<VariableSymbol *>(8);
  501.         formal_parameters -> Next() = variable;
  502.     }
  503.  
  504.     int NumThrows()
  505.     {
  506.         assert(! throws_signatures);
  507.  
  508.         return (throws ? throws -> Length() : 0);
  509.     }
  510.     TypeSymbol *Throws(int i)
  511.     {
  512.         return (*throws)[i];
  513.     }
  514.     void AddThrows(TypeSymbol *exception)
  515.     {
  516.         if (! throws)
  517.             throws = new Tuple<TypeSymbol *>(8);
  518.         throws -> Next() = exception;
  519.     }
  520.  
  521.     int NumThrowsSignatures()
  522.     {
  523.         return (throws_signatures ? throws_signatures -> Length() : 0);
  524.     }
  525.     char *ThrowsSignature(int i)
  526.     {
  527.         return (*throws_signatures)[i];
  528.     }
  529.     void AddThrowsSignature(char *signature_, int length)
  530.     {
  531.         char *signature = new char[length + 1];
  532.         strncpy(signature, signature_, length);
  533.         signature[length] = U_NULL;
  534.  
  535.         if (! throws_signatures)
  536.             throws_signatures = new Tuple<char *>(8);
  537.         throws_signatures -> Next() = signature;
  538.     }
  539.  
  540.     void SetGeneratedLocalConstructor(MethodSymbol *base_method)
  541.     {
  542.         assert(! base_method -> local_constructor);
  543.  
  544.         base_method -> local_constructor = this;
  545.         this -> local_constructor = base_method;
  546.     }
  547.     bool IsGeneratedLocalConstructor() { return ((local_constructor != NULL) && (this -> external_name_symbol == NULL)); }
  548.     MethodSymbol *LocalConstructor()  { return local_constructor; }
  549.  
  550.     void SetExternalIdentity(NameSymbol *external_name_symbol_) { external_name_symbol = external_name_symbol_; }
  551.     NameSymbol *ExternalIdentity()
  552.     {
  553.         return (external_name_symbol ? external_name_symbol : name_symbol);
  554.     }
  555.     wchar_t *ExternalName()
  556.     {
  557.         return (external_name_symbol ? external_name_symbol -> Name() : name_symbol -> Name());
  558.     }
  559.     int ExternalNameLength()
  560.     {
  561.         return (external_name_symbol ? external_name_symbol -> NameLength() : name_symbol -> NameLength());
  562.     }
  563.     char *ExternalUtf8Name()
  564.     {
  565.         return (char *) (external_name_symbol ? external_name_symbol -> Utf8_literal -> value
  566.                                               : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL));
  567.     }
  568.     int ExternalUtf8NameLength()
  569.     {
  570.         return (external_name_symbol ? (external_name_symbol -> Utf8_literal ? external_name_symbol -> Utf8_literal -> length : 0)
  571.                                      : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0));
  572.     }
  573.  
  574.     void SetContainingType(TypeSymbol *containing_type_) { containing_type = containing_type_; }
  575.     void SetBlockSymbol(BlockSymbol *block_symbol_) { block_symbol = block_symbol_; }
  576.     void SetSignature(Control &, VariableSymbol * = NULL);
  577.     void SetSignature(Utf8LiteralValue *signature_) { signature = signature_; }
  578.     char *SignatureString() { return signature -> value; }
  579.     wchar_t *Header();
  580.  
  581.     void CleanUp();
  582.  
  583.     void MarkSynthetic() { status |= (unsigned char) 0x08; }
  584.     bool IsSynthetic()   { return (status & (unsigned char) 0x08) != 0; }
  585.  
  586.     void MarkDeprecated() { status |= (unsigned char) 0x10; }
  587.     bool IsDeprecated()   { return (status & (unsigned char) 0x10) != 0; }
  588.  
  589. private:
  590.     NameSymbol *external_name_symbol;
  591.  
  592.     unsigned char status;
  593.     wchar_t *header;
  594.  
  595.     TypeSymbol *type_;
  596.     Tuple<VariableSymbol *> *formal_parameters;
  597.     Tuple<TypeSymbol *> *throws;
  598.     Tuple<char *> *throws_signatures;
  599.     Tuple<MethodSymbol *> *initializer_constructors;
  600.  
  601.     //
  602.     // If the method in question is a constructor of a local type, we may need to construct
  603.     // another constructor that accepts extra local parameters.
  604.     //
  605.     MethodSymbol *local_constructor;
  606.  
  607.     bool ACC_FINAL()
  608.     {
  609.         assert(! "use the ACC_FINAL() flag on a method symbol. Use the function IsFinal() instead");
  610.  
  611.         return false;
  612.     }
  613. };
  614.  
  615.  
  616. class TypeSymbol : public Symbol, public AccessFlags
  617. {
  618. public:
  619.     SemanticEnvironment *semantic_environment;
  620.     Ast *declaration;  // AstClassDeclaration or AstInterfaceDeclaration
  621.     FileSymbol *file_symbol;
  622.     FileLocation *file_location;
  623.     NameSymbol *name_symbol;
  624.     Symbol *owner;
  625.     TypeSymbol *outermost_type; // An nested class identifies the outer most type that contains it.
  626.                                 // If a class is not nested then it identifies itself as its outer
  627.                                 // most type.
  628.     TypeSymbol *super,
  629.                *base_type; // indicates the base type (type of elements in the last dimension) of an array
  630.                            // For a normal type base_type is NULL. If base_type is a "bad" type it points
  631.                            // to itself (this).
  632.     int index,             // This variable is used in TypeCycleChecker to determine if this type
  633.                            // forms an inter-type cycle in its "extends" or "implements" relationship.
  634.                            //
  635.         unit_index,        // This variable is used in TypeCycleChecker to check if this type
  636.                            // forms an intra-type cycle in its "extends" or "implements" relationship;
  637.                            //
  638.         incremental_index; // This variable is used in TypeCycleChecker to determine which types (files)
  639.                            // need to be recompiled based on the "dependent" relationship.
  640.  
  641.     int NumLocalConstructorCallEnvironments() { return (local_constructor_call_environments ? local_constructor_call_environments -> Length() : 0); }
  642.     SemanticEnvironment *&LocalConstructorCallEnvironment(int i) { return (*local_constructor_call_environments)[i]; }
  643.     void AddLocalConstructorCallEnvironment(SemanticEnvironment *environment)
  644.     {
  645.         if (! local_constructor_call_environments)
  646.             local_constructor_call_environments = new Tuple<SemanticEnvironment *>(8);
  647.         local_constructor_call_environments -> Next() = environment;
  648.     }
  649.  
  650.     int NumPrivateAccessMethods() { return (private_access_methods ? private_access_methods -> Length() : 0); }
  651.     MethodSymbol *&PrivateAccessMethod(int i) { return (*private_access_methods)[i]; }
  652.     void AddPrivateAccessMethod(MethodSymbol *method_symbol)
  653.     {
  654.         if (! private_access_methods)
  655.             private_access_methods = new Tuple<MethodSymbol *>(8);
  656.         private_access_methods -> Next() = method_symbol;
  657.     }
  658.  
  659.     int NumPrivateAccessConstructors() { return (private_access_constructors ? private_access_constructors -> Length() : 0); }
  660.     MethodSymbol *&PrivateAccessConstructor(int i) { return (*private_access_constructors)[i]; }
  661.     void AddPrivateAccessConstructor(MethodSymbol *constructor_symbol)
  662.     {
  663.         if (! private_access_constructors)
  664.             private_access_constructors = new Tuple<MethodSymbol *>(8);
  665.         private_access_constructors -> Next() = constructor_symbol;
  666.     }
  667.  
  668.     int NumConstructorParameters() { return (constructor_parameters ? constructor_parameters -> Length() : 0); }
  669.     VariableSymbol *&ConstructorParameter(int i) { return (*constructor_parameters)[i]; }
  670.     void AddConstructorParameter(VariableSymbol *variable_symbol)
  671.     {
  672.         if (! constructor_parameters)
  673.             constructor_parameters = new Tuple<VariableSymbol *>(8);
  674.         constructor_parameters -> Next() = variable_symbol;
  675.     }
  676.  
  677.     int NumGeneratedConstructors() { return (generated_constructors ? generated_constructors -> Length() : 0); }
  678.     MethodSymbol *&GeneratedConstructor(int i) { return (*generated_constructors)[i]; }
  679.     void AddGeneratedConstructor(MethodSymbol *constructor_symbol)
  680.     {
  681.         if (! generated_constructors)
  682.             generated_constructors = new Tuple<MethodSymbol *>(8);
  683.         generated_constructors -> Next() = constructor_symbol;
  684.     }
  685.  
  686.     int NumEnclosingInstances() { return (enclosing_instances ? enclosing_instances -> Length() : 0); }
  687.     VariableSymbol *&EnclosingInstance(int i) { return (*enclosing_instances)[i]; }
  688.     void AddEnclosingInstance(VariableSymbol *instance_symbol)
  689.     {
  690.         if (! enclosing_instances)
  691.             enclosing_instances = new Tuple<VariableSymbol *>(8);
  692.         enclosing_instances -> Next() = instance_symbol;
  693.     }
  694.  
  695.     int NumClassLiterals() { return (class_literals ? class_literals -> Length() : 0); }
  696.     VariableSymbol *&ClassLiteral(int i) { return (*class_literals)[i]; }
  697.     void AddClassLiteral(VariableSymbol *literal_symbol)
  698.     {
  699.         if (! class_literals)
  700.             class_literals = new Tuple<VariableSymbol *>(8);
  701.         class_literals -> Next() = literal_symbol;
  702.     }
  703.  
  704.     int NumNestedTypes() { return (nested_types ? nested_types -> Length() : 0); }
  705.     TypeSymbol *&NestedType(int i) { return (*nested_types)[i]; }
  706.     void AddNestedType(TypeSymbol *type_symbol)
  707.     {
  708.         if (! nested_types)
  709.             nested_types = new Tuple<TypeSymbol *>(8);
  710.         nested_types -> Next() = type_symbol;
  711.     }
  712.  
  713.     int NumInterfaces() { return (interfaces ? interfaces -> Length() : 0); }
  714.     void ResetInterfaces()
  715.     {
  716.         delete interfaces;
  717.         interfaces = NULL;
  718.     }
  719.     TypeSymbol *Interface(int i) { return (*interfaces)[i]; }
  720.     void AddInterface(TypeSymbol *type_symbol)
  721.     {
  722.         if (! interfaces)
  723.             interfaces = new Tuple<TypeSymbol *>(8);
  724.         interfaces -> Next() = type_symbol;
  725.     }
  726.  
  727.     int num_anonymous_types() { return (anonymous_types ? anonymous_types -> Length() : 0); }
  728.     TypeSymbol *&AnonymousType(int i) { return (*anonymous_types)[i]; }
  729.     void AddAnonymousType(TypeSymbol *type_symbol)
  730.     {
  731.         if (! anonymous_types)
  732.             anonymous_types = new Tuple<TypeSymbol *>(8);
  733.         anonymous_types -> Next() = type_symbol;
  734.     }
  735.     void DeleteAnonymousTypes();
  736.  
  737.     SymbolSet *local,
  738.               *non_local;
  739.  
  740.     SymbolSet *supertypes_closure,
  741.               *subtypes,
  742.               *subtypes_closure,
  743.               *innertypes_closure;
  744.  
  745.     SymbolSet *dependents,
  746.               *parents,
  747.               *static_parents,
  748.               *dependents_closure,  // processed in cycle.cpp
  749.               *parents_closure;     // processed in cycle.cpp
  750.  
  751.     int pool_index; // index of element in symbol_pool (in the relevant symbol table) that points to this type
  752.  
  753.     Utf8LiteralValue *signature;
  754.     Utf8LiteralValue *fully_qualified_name;
  755.  
  756.     ExpandedTypeTable *expanded_type_table;
  757.     ExpandedFieldTable *expanded_field_table;
  758.     ExpandedMethodTable *expanded_method_table;
  759.  
  760.     int num_dimensions;
  761.  
  762.     MethodSymbol *static_initializer_method;
  763.     MethodSymbol *block_initializer_method;
  764.  
  765.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  766.     virtual size_t NameLength() { return name_symbol -> NameLength(); }
  767.     virtual NameSymbol *Identity() { return name_symbol; }
  768.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  769.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  770.  
  771.  
  772.     void SetExternalIdentity(NameSymbol *external_name_symbol_) { external_name_symbol = external_name_symbol_; }
  773.     NameSymbol *ExternalIdentity()
  774.     {
  775.         return (external_name_symbol ? external_name_symbol : name_symbol);
  776.     }
  777.     wchar_t *ExternalName()
  778.     {
  779.         return (external_name_symbol ? external_name_symbol -> Name() : name_symbol -> Name());
  780.     }
  781.     int ExternalNameLength()
  782.     {
  783.         return (external_name_symbol ? external_name_symbol -> NameLength() : name_symbol -> NameLength());
  784.     }
  785.     char *ExternalUtf8Name()
  786.     {
  787.         return (char *) (external_name_symbol ? external_name_symbol -> Utf8_literal -> value
  788.                                               : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL));
  789.     }
  790.     int ExternalUtf8NameLength()
  791.     {
  792.         return (external_name_symbol ? (external_name_symbol -> Utf8_literal ? external_name_symbol -> Utf8_literal -> length : 0)
  793.                                      : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0));
  794.     }
  795.  
  796.     TypeSymbol(NameSymbol *);
  797.     virtual ~TypeSymbol();
  798.  
  799.     void ProcessTypeHeaders();
  800.     void ProcessMembers();
  801.     void CompleteSymbolTable();
  802.     void ProcessExecutableBodies();
  803.     void RemoveCompilationReferences();
  804.  
  805.     NameSymbol *GetThisName(Control &, int);
  806.  
  807.     VariableSymbol *FindThis(int k)
  808.     {
  809.         assert(IsInner());
  810.         assert(NumConstructorParameters() > 0);
  811.  
  812.         return (k == 0 ? ConstructorParameter(0)
  813.                        : (VariableSymbol *) (NumEnclosingInstances() > k ? EnclosingInstance(k) : NULL));
  814.     }
  815.     VariableSymbol *InsertThis(int k);
  816.  
  817.     TypeSymbol *FindOrInsertClassLiteralClass(LexStream::TokenIndex);
  818.     TypeSymbol *ClassLiteralClass()
  819.     {
  820.         return class_literal_class;
  821.     }
  822.     MethodSymbol *FindOrInsertClassLiteralMethod(Control &);
  823.     MethodSymbol *ClassLiteralMethod()
  824.     {
  825.         return class_literal_method;
  826.     }
  827.     Utf8LiteralValue *FindOrInsertClassLiteralName(Control &);
  828.     Utf8LiteralValue *ClassLiteralName()
  829.     {
  830.         return class_literal_name;
  831.     }
  832.     VariableSymbol *FindOrInsertClassLiteral(TypeSymbol *);
  833.     VariableSymbol *FindOrInsertLocalShadow(VariableSymbol *);
  834.  
  835.     MethodSymbol *GetReadAccessMethod(MethodSymbol *);
  836.     MethodSymbol *GetReadAccessMethod(VariableSymbol *);
  837.     MethodSymbol *GetWriteAccessMethod(VariableSymbol *);
  838.  
  839.     bool IsArray() { return (num_dimensions > 0); }
  840.  
  841.     void SetOwner(Symbol *owner_) { owner = owner_; }
  842.     bool IsOwner(TypeSymbol *type)
  843.     {
  844.         Symbol *sym = type -> owner;
  845.         while (! sym -> PackageCast())
  846.         {
  847.             if (sym == this)
  848.                 return true;
  849.  
  850.             MethodSymbol *method = sym -> MethodCast();
  851.             sym = (method ? method -> containing_type : ((TypeSymbol *) sym) -> owner);
  852.         }
  853.  
  854.         return false;
  855.     }
  856.  
  857.     TypeSymbol *ContainingType()
  858.     {
  859.         if (owner)
  860.         {
  861.             TypeSymbol *type = owner -> TypeCast();
  862.             if (type)
  863.                 return type;
  864.             MethodSymbol *method = owner -> MethodCast();
  865.             if (method)
  866.                 return method -> containing_type;
  867.         }
  868.  
  869.         return NULL;
  870.     }
  871.  
  872.     bool CanAccess(TypeSymbol *);
  873.  
  874.     bool HasProtectedAccessTo(TypeSymbol *);
  875.  
  876.     bool IsSubclass(TypeSymbol *super_class)
  877.     {
  878.         return (this == super_class ? true : (super == NULL ? false : super -> IsSubclass(super_class)));
  879.     }
  880.  
  881.     bool IsSubinterface(TypeSymbol *super_interface)
  882.     {
  883.         if (this == super_interface)
  884.             return true;
  885.         for (int i = 0; i < NumInterfaces(); i++)
  886.         {
  887.             if (Interface(i) -> IsSubinterface(super_interface))
  888.                 return true;
  889.         }
  890.         return false;
  891.     }
  892.  
  893.     bool Implements(TypeSymbol *inter)
  894.     {
  895.         for (int i = 0; i < NumInterfaces(); i++)
  896.         {
  897.             if (Interface(i) -> IsSubinterface(inter))
  898.                 return true;
  899.         }
  900.         return (this -> super ? this -> super -> Implements(inter) : false);
  901.     }
  902.  
  903.     wchar_t *FileLoc()
  904.     {
  905.         return (wchar_t *) (file_location ? file_location -> location : NULL);
  906.     }
  907.  
  908.     void SetLocation();
  909.  
  910.     TypeSymbol *GetArrayType(Semantic *, int);
  911.  
  912.     TypeSymbol *ArraySubtype()
  913.     {
  914.         return this -> base_type -> Array(this -> num_dimensions - 1);
  915.     }
  916.  
  917.     void SetSignature(Control &);
  918.     void SetSignature(Utf8LiteralValue *signature_) { signature = signature_; }
  919.     char *SignatureString() { return signature -> value; }
  920.  
  921.     void SetClassLiteralName(Utf8LiteralValue *class_literal_name_) { class_literal_name = class_literal_name_; }
  922.  
  923.     PackageSymbol *ContainingPackage() { return outermost_type -> owner -> PackageCast(); }
  924.  
  925.     bool IsNestedIn(TypeSymbol *);
  926.  
  927.     bool IsNested() { return outermost_type != this; }
  928.  
  929.     bool IsTopLevel() { return (! IsNested()) || this -> ACC_STATIC(); }
  930.  
  931.     bool IsInner() { return (! IsTopLevel()); }
  932.  
  933.     bool IsLocal()
  934.     {
  935.         for (Symbol *sym = owner; ! sym -> PackageCast(); sym = ((TypeSymbol *) sym) -> owner)
  936.         {
  937.             if (sym -> MethodCast())
  938.                 return true;
  939.         }
  940.  
  941.         return false;
  942.     }
  943.  
  944.     inline char *ClassName()
  945.     {
  946.         if (! class_name)
  947.             SetClassName();
  948.         return class_name;
  949.     }
  950.  
  951.     void MarkConstructorMembersProcessed() { status |= (unsigned short) 0x0001; }
  952.     bool ConstructorMembersProcessed() { return (status & (unsigned short) 0x0001) != 0 ; }
  953.  
  954.     void MarkMethodMembersProcessed() { status |= (unsigned short) 0x0002; }
  955.     bool MethodMembersProcessed() { return (status & (unsigned short) 0x0002) != 0; }
  956.  
  957.     void MarkFieldMembersProcessed() { status |= (unsigned short) 0x0004; }
  958.     bool FieldMembersProcessed() { return (status & (unsigned short) 0x0004) != 0; }
  959.  
  960.     void MarkLocalClassProcessingCompleted() { status |= (unsigned short) 0x0008; }
  961.     bool LocalClassProcessingCompleted() { return (status & (unsigned short) 0x0008) != 0; }
  962.  
  963.     void MarkSourcePending() { status |= (unsigned short) 0x0010; }
  964.     void MarkSourceNoLongerPending() { status &= (~ ((unsigned short) 0x0010)); }
  965.     bool SourcePending() { return (status & (unsigned short) 0x0010) != 0; }
  966.  
  967.     void MarkAnonymous() { status |= (unsigned short) 0x0020; }
  968.     bool Anonymous() { return (status & (unsigned short) 0x0020) != 0; }
  969.  
  970.     void MarkHeaderProcessed() { status |= (unsigned short) 0x0040; }
  971.     bool HeaderProcessed() { return (status & (unsigned short) 0x0040) != 0; }
  972.  
  973.     void MarkPrimitive() { status |= (unsigned short) 0x0080; }
  974.     bool Primitive()     { return (status & (unsigned short) 0x0080) != 0; }
  975.  
  976.     void MarkDeprecated() { status |= (unsigned short) 0x0100; }
  977.     bool IsDeprecated()   { return (status & (unsigned short) 0x0100) != 0; }
  978.  
  979.     void MarkBad()
  980.     {
  981.         SetACC_PUBLIC();
  982.  
  983.         status |= (unsigned short) 0x0200;
  984.  
  985.         MarkHeaderProcessed();
  986.         MarkConstructorMembersProcessed();
  987.         MarkMethodMembersProcessed();
  988.         MarkFieldMembersProcessed();
  989.         MarkLocalClassProcessingCompleted();
  990.         MarkSourceNoLongerPending();
  991.  
  992.         return;
  993.     }
  994.     bool Bad() { return (status & (unsigned short) 0x0200) != 0; }
  995.  
  996.     void MarkCircular()
  997.     {
  998.         status |= (unsigned short) 0x0400;
  999.         MarkBad();
  1000.         return;
  1001.     }
  1002.     void MarkNonCircular() { status &= (~ ((unsigned short) 0x0400)); }
  1003.     bool Circular() { return (status & (unsigned short) 0x0400) != 0; }
  1004.  
  1005.     void ProcessNestedTypeSignatures(Semantic *, LexStream::TokenIndex);
  1006.  
  1007.     bool NestedTypesProcessed() { return nested_type_signatures == NULL; }
  1008.  
  1009.     int NumNestedTypeSignatures()
  1010.     {
  1011.         return (nested_type_signatures ? nested_type_signatures -> Length() : 0);
  1012.     }
  1013.     char *NestedTypeSignature(int i)
  1014.     {
  1015.         return (*nested_type_signatures)[i];
  1016.     }
  1017.     void AddNestedTypeSignature(char *signature_, int length)
  1018.     {
  1019.         char *signature = new char[length + 1];
  1020.         strncpy(signature, signature_, length);
  1021.         signature[length] = U_NULL;
  1022.  
  1023.         if (! nested_type_signatures)
  1024.             nested_type_signatures = new Tuple<char *>(8);
  1025.         nested_type_signatures -> Next() = signature;
  1026.     }
  1027.  
  1028.     inline void SetSymbolTable(int);
  1029.     inline SymbolTable *Table();
  1030.  
  1031.     int NumVariableSymbols();
  1032.     VariableSymbol *VariableSym(int);
  1033.  
  1034.     int NumMethodSymbols();
  1035.     MethodSymbol *MethodSym(int);
  1036.  
  1037.     int NumTypeSymbols();
  1038.     TypeSymbol *TypeSym(int);
  1039.  
  1040.     inline TypeSymbol *InsertAnonymousTypeSymbol(NameSymbol *);
  1041.     inline TypeSymbol *FindTypeSymbol(NameSymbol *);
  1042.     inline TypeSymbol *InsertNestedTypeSymbol(NameSymbol *);
  1043.     inline MethodSymbol *FindConstructorSymbol();
  1044.     inline MethodSymbol *InsertConstructorSymbol(NameSymbol *);
  1045.     inline void InsertConstructorSymbol(MethodSymbol *);
  1046.     inline MethodSymbol *FindMethodSymbol(NameSymbol *);
  1047.     inline VariableSymbol *FindVariableSymbol(NameSymbol *);
  1048.     inline VariableSymbol *InsertVariableSymbol(NameSymbol *);
  1049.     inline void InsertVariableSymbol(VariableSymbol *);
  1050.  
  1051.     inline MethodSymbol *InsertMethodSymbol(NameSymbol *);
  1052.     inline void InsertMethodSymbol(MethodSymbol *);
  1053.     inline MethodSymbol *Overload(MethodSymbol *);
  1054.     inline void Overload(MethodSymbol *, MethodSymbol *);
  1055.     inline MethodSymbol *LocalConstructorOverload(MethodSymbol *);
  1056.     MethodSymbol *FindOverloadMethod(MethodSymbol *, AstMethodDeclarator *);
  1057.  
  1058.     inline void CompressSpace();
  1059.  
  1060. private:
  1061.     //
  1062.     // The fields hash_address and next_type are used in the class TypeLookupTable
  1063.     // to contruct a mapping from each fully_qualified name into the type that it defines.
  1064.     //
  1065.     friend TypeLookupTable;
  1066.     unsigned hash_address;
  1067.     TypeSymbol *next_type;
  1068.  
  1069.     NameSymbol *external_name_symbol;
  1070.  
  1071.     SymbolTable *table;
  1072.     SymbolMap *local_shadow_map;
  1073.  
  1074.     unsigned short status;
  1075.  
  1076.     PackageSymbol *package;
  1077.     char *class_name;
  1078.  
  1079.     void SetClassName();
  1080.  
  1081.     TypeSymbol *class_literal_class;
  1082.     MethodSymbol *class_literal_method;
  1083.     Utf8LiteralValue *class_literal_name;
  1084.  
  1085.     //
  1086.     // For a local type, when we first encounter an embedded call
  1087.     // to one of its constructors or a constructor of one of its inner
  1088.     // types, either via a ClassInstanceCreation or an ExplicitConstructorInvocation,
  1089.     // we record it and resolve it after we have computed all necessary
  1090.     // information about the type and its inner types.
  1091.     //
  1092.     Tuple<SemanticEnvironment *> *local_constructor_call_environments;
  1093.  
  1094.     //
  1095.     // When an inner class tries to access a private member of one of its enclosing
  1096.     // classes, one (or two) access method(s) to read (and/or write) the private member
  1097.     // is (are) generated.
  1098.     //
  1099.     // The maps read_method and write_method are used to keep track of the read and
  1100.     // write method to which a member has been mapped.
  1101.     //
  1102.     Tuple<MethodSymbol *> *private_access_methods,
  1103.                           *private_access_constructors;
  1104.  
  1105.     inline void MapSymbolToReadMethod(Symbol *, MethodSymbol *);
  1106.     inline MethodSymbol *ReadMethod(Symbol *);
  1107.     inline void MapSymbolToWriteMethod(VariableSymbol *, MethodSymbol *);
  1108.     inline MethodSymbol *WriteMethod(VariableSymbol *);
  1109.  
  1110.     SymbolMap *read_method,
  1111.               *write_method;
  1112.  
  1113.     //
  1114.     // For an accessible inner class the first elememt in this array
  1115.     // identifies the "this$0" pointer of the containing type. For a local
  1116.     // class, in addition to the this$0 pointer (if it is needed), all local
  1117.     // variables that are referred to in the local type are passed as argument
  1118.     // to the local type and copied in the constructor into a local field. These
  1119.     // local variables are stored in constructor_parameters.
  1120.     //
  1121.     // The array enclosing_instances is there for optimization purposes.
  1122.     // If this type is deeply nested within several other types and it makes
  1123.     // references to members in the enclosing types, then it might
  1124.     // be useful to keep a reference to each of these enclosing
  1125.     // instances in the form of this$0, this$1, this$2, ...
  1126.     //
  1127.     // The array class_identities is used to store static variables of type Class
  1128.     // that contain the proper value for a given type.
  1129.     //
  1130.     Tuple<VariableSymbol *> *constructor_parameters;
  1131.     Tuple<MethodSymbol *> *generated_constructors;
  1132.     Tuple<VariableSymbol *> *enclosing_instances;
  1133.     Tuple<VariableSymbol *> *class_literals;
  1134.  
  1135.     Tuple<char *> *nested_type_signatures;
  1136.  
  1137.     //
  1138.     // The inner types that appear immediately within this type in the order
  1139.     // in which they should be processed (compiled).
  1140.     Tuple<TypeSymbol *> *nested_types;
  1141.  
  1142.     //
  1143.     // The interfaces that were declared in the header of the type.
  1144.     //
  1145.     Tuple<TypeSymbol *> *interfaces;
  1146.  
  1147.     //
  1148.     // The anonymous types that were declared in this type.
  1149.     //
  1150.     Tuple<TypeSymbol *> *anonymous_types;
  1151.  
  1152.     //
  1153.     // The arrays of this type that were declared.
  1154.     //
  1155.     Tuple<TypeSymbol *> *array;
  1156.     inline int NumArrays()
  1157.     {
  1158.         return (array ? array -> Length() : 0);
  1159.     }
  1160.     inline TypeSymbol *Array(int i)
  1161.     {
  1162.         return (*array)[i];
  1163.     }
  1164.     inline void AddArrayType(TypeSymbol *type_symbol)
  1165.     {
  1166.         if (! array)
  1167.             array = new Tuple<TypeSymbol *>(4);
  1168.         array -> Next() = type_symbol;
  1169.     }
  1170. };
  1171.  
  1172.  
  1173. class VariableSymbol : public Symbol, public AccessFlags
  1174. {
  1175. public:
  1176.     AstVariableDeclarator *declarator;
  1177.  
  1178.     NameSymbol *name_symbol;
  1179.     Symbol     *owner;
  1180.     LiteralValue *initial_value;
  1181.  
  1182.     VariableSymbol *accessed_local;
  1183.  
  1184.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  1185.     virtual size_t NameLength() { return name_symbol -> NameLength(); }
  1186.     virtual NameSymbol *Identity() { return name_symbol; }
  1187.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  1188.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  1189.  
  1190.     void SetExternalIdentity(NameSymbol *external_name_symbol_) { external_name_symbol = external_name_symbol_; }
  1191.     NameSymbol *ExternalIdentity()
  1192.     {
  1193.         return (external_name_symbol ? external_name_symbol : name_symbol);
  1194.     }
  1195.     wchar_t *ExternalName()
  1196.     {
  1197.         return (external_name_symbol ? external_name_symbol -> Name() : name_symbol -> Name());
  1198.     }
  1199.     int ExternalNameLength()
  1200.     {
  1201.         return (external_name_symbol ? external_name_symbol -> NameLength() : name_symbol -> NameLength());
  1202.     }
  1203.     char *ExternalUtf8Name()
  1204.     {
  1205.         return (char *) (external_name_symbol ? external_name_symbol -> Utf8_literal -> value
  1206.                                               : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL));
  1207.     }
  1208.     int ExternalUtf8NameLength()
  1209.     {
  1210.         return (external_name_symbol ? (external_name_symbol -> Utf8_literal ? external_name_symbol -> Utf8_literal -> length : 0)
  1211.                                      : (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0));
  1212.     }
  1213.  
  1214.     VariableSymbol(NameSymbol *name_symbol_) : declarator(NULL),
  1215.                                                name_symbol(name_symbol_),
  1216.                                                owner(NULL),
  1217.                                                initial_value(NULL),
  1218.                                                accessed_local(NULL),
  1219.                                                external_name_symbol(NULL),
  1220.                                                status(0),
  1221.                                                local_variable_index_(-1),
  1222.                                                type_(NULL),
  1223.                                                signature_string(NULL)
  1224.     {
  1225.         Symbol::_kind = VARIABLE;
  1226.     }
  1227.  
  1228.     virtual ~VariableSymbol() { delete [] signature_string; }
  1229.  
  1230.     void SetOwner(Symbol *owner_) { owner = owner_; }
  1231.  
  1232.     void SetLocalVariableIndex(int index)
  1233.     {
  1234.         local_variable_index_ = index;
  1235.         MarkComplete();
  1236.     }
  1237.     int LocalVariableIndex() { return local_variable_index_; }
  1238.  
  1239.     bool IsTyped()
  1240.     {
  1241.         return type_ != NULL;
  1242.     }
  1243.  
  1244.     void SetType(TypeSymbol *_type)
  1245.     {
  1246.         type_ = _type;
  1247.     }
  1248.  
  1249.     void ProcessVariableSignature(Semantic *, LexStream::TokenIndex);
  1250.  
  1251.     TypeSymbol *Type()
  1252.     {
  1253.         assert(type_); // make sure that the method signature associated with this method is processed prior to invoking
  1254.                        // this function. ( "this -> ProcessVariableSignature(sem, tok);" )
  1255.  
  1256.         return type_;
  1257.     }
  1258.  
  1259.     void SetSignatureString(char *signature_, int length)
  1260.     {
  1261.         signature_string = new char[length + 1];
  1262.         strncpy(signature_string, signature_, length);
  1263.         signature_string[length] = U_NULL;
  1264.     }
  1265.  
  1266.     bool IsLocal()                     { return owner -> MethodCast() != NULL; }           // is variable a local variable?
  1267.     bool IsLocal(MethodSymbol *method) { return owner == method; } // is variable local to a particular method ?
  1268.     bool IsFinal(TypeSymbol *type)     { return (owner == type && ACC_FINAL()); }
  1269.  
  1270.     //
  1271.     // These functions are used to identify when the declaration of a field in the body of a class is
  1272.     // complete.
  1273.     //
  1274.     void MarkIncomplete()         { status &= (~((unsigned char) 0x01)); }
  1275.     void MarkComplete()           { status |= (unsigned char) 0x01; }
  1276.     bool IsDeclarationComplete()  { return (status & (unsigned char) 0x01) != 0; }
  1277.  
  1278.     void MarkNotDefinitelyAssigned() { status &= (~((unsigned char) 0x02)); }
  1279.     void MarkDefinitelyAssigned()    { status |= (unsigned char) 0x02; }
  1280.     bool IsDefinitelyAssigned()      { return (status & (unsigned char) 0x02) != 0; }
  1281.  
  1282.     void MarkPossiblyAssigned() { status |= (unsigned char) 0x04; }
  1283.     bool IsPossiblyAssigned()   { return (status & (unsigned char) 0x04) != 0; }
  1284.  
  1285.     void MarkSynthetic() { status |= (unsigned char) 0x08; }
  1286.     bool IsSynthetic()   { return (status & (unsigned char) 0x08) != 0; }
  1287.  
  1288.     void MarkDeprecated() { status |= (unsigned char) 0x10; }
  1289.     bool IsDeprecated()   { return (status & (unsigned char) 0x10) != 0; }
  1290.  
  1291. private:
  1292.     NameSymbol *external_name_symbol;
  1293.  
  1294.     unsigned char status;
  1295.     int local_variable_index_;
  1296.     TypeSymbol *type_;
  1297.     char *signature_string;
  1298. };
  1299.  
  1300.  
  1301. class BlockSymbol : public Symbol
  1302. {
  1303. public:
  1304.     int max_variable_index,
  1305.         try_or_synchronized_variable_index;
  1306.  
  1307.     BlockSymbol(int hash_size);
  1308.     virtual ~BlockSymbol();
  1309.  
  1310.     int NumVariableSymbols();
  1311.     VariableSymbol *VariableSym(int);
  1312.  
  1313.     inline VariableSymbol *FindVariableSymbol(NameSymbol *);
  1314.     inline VariableSymbol *InsertVariableSymbol(NameSymbol *);
  1315.     inline void InsertVariableSymbol(VariableSymbol *);
  1316.     inline BlockSymbol *InsertBlockSymbol(int);
  1317.  
  1318.     inline void CompressSpace();
  1319.  
  1320.     inline SymbolTable *Table();
  1321.  
  1322. private:
  1323.  
  1324.     SymbolTable *table;
  1325. };
  1326.  
  1327.  
  1328. class LabelSymbol : public Symbol
  1329. {
  1330. public:
  1331.     AstBlock *block; // the block that is labeled by this symbol
  1332.     NameSymbol *name_symbol;
  1333.  
  1334.     int nesting_level;
  1335.  
  1336.     virtual wchar_t *Name() { return name_symbol -> Name(); }
  1337.     virtual size_t NameLength() { return name_symbol -> NameLength(); }
  1338.     virtual NameSymbol *Identity() { return name_symbol; }
  1339.     char *Utf8Name() { return (char *) (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> value : NULL); }
  1340.     int Utf8NameLength() { return (name_symbol -> Utf8_literal ? name_symbol -> Utf8_literal -> length : 0); }
  1341.  
  1342.     LabelSymbol(NameSymbol *name_symbol_) : block(NULL),
  1343.                                             name_symbol(name_symbol_),
  1344.                                             nesting_level(0)
  1345.     {
  1346.         Symbol::_kind = LABEL;
  1347.     }
  1348.  
  1349.     virtual ~LabelSymbol() {}
  1350.  
  1351. private:
  1352. };
  1353.  
  1354.  
  1355. class SymbolTable
  1356. {
  1357. public:
  1358.     enum
  1359.     {
  1360.         DEFAULT_HASH_SIZE = 13,
  1361.         MAX_HASH_SIZE = 1021
  1362.     };
  1363.  
  1364.     int NumAnonymousSymbols()
  1365.     {
  1366.         return (anonymous_symbol_pool ? anonymous_symbol_pool -> Length() : 0);
  1367.     }
  1368.     TypeSymbol *AnonymousSym(int i)
  1369.     {
  1370.         return (*anonymous_symbol_pool)[i];
  1371.     }
  1372.     void AddAnonymousSymbol(TypeSymbol *symbol)
  1373.     {
  1374.         if (! anonymous_symbol_pool)
  1375.             anonymous_symbol_pool = new ConvertibleArray<TypeSymbol *>(256);
  1376.         anonymous_symbol_pool -> Next() = symbol;
  1377.     }
  1378.  
  1379.     int NumTypeSymbols()
  1380.     {
  1381.         return (type_symbol_pool ? type_symbol_pool -> Length() : 0);
  1382.     }
  1383.     TypeSymbol *&TypeSym(int i)
  1384.     {
  1385.         return (*type_symbol_pool)[i];
  1386.     }
  1387.     void AddTypeSymbol(TypeSymbol *symbol)
  1388.     {
  1389.         if (! type_symbol_pool)
  1390.             type_symbol_pool = new ConvertibleArray<TypeSymbol *>(256);
  1391.         type_symbol_pool -> Next() = symbol;
  1392.     }
  1393.  
  1394.     int NumMethodSymbols()
  1395.     {
  1396.         return (method_symbol_pool ? method_symbol_pool -> Length() : 0);
  1397.     }
  1398.     MethodSymbol *MethodSym(int i)
  1399.     {
  1400.         return (*method_symbol_pool)[i];
  1401.     }
  1402.     void AddMethodSymbol(MethodSymbol *symbol)
  1403.     {
  1404.         if (! method_symbol_pool)
  1405.             method_symbol_pool = new ConvertibleArray<MethodSymbol *>(256);
  1406.         method_symbol_pool -> Next() = symbol;
  1407.     }
  1408.  
  1409.     int NumVariableSymbols()
  1410.     {
  1411.         return (variable_symbol_pool ? variable_symbol_pool -> Length() : 0);
  1412.     }
  1413.     VariableSymbol *VariableSym(int i)
  1414.     {
  1415.         return (*variable_symbol_pool)[i];
  1416.     }
  1417.     void AddVariableSymbol(VariableSymbol *symbol)
  1418.     {
  1419.         if (! variable_symbol_pool)
  1420.             variable_symbol_pool = new ConvertibleArray<VariableSymbol *>(256);
  1421.         variable_symbol_pool -> Next() = symbol;
  1422.     }
  1423.  
  1424.     int NumOtherSymbols()
  1425.     {
  1426.         return (other_symbol_pool ? other_symbol_pool -> Length() : 0);
  1427.     }
  1428.     Symbol *OtherSym(int i)
  1429.     {
  1430.         return (*other_symbol_pool)[i];
  1431.     }
  1432.     void AddOtherSymbol(Symbol *symbol)
  1433.     {
  1434.         if (! other_symbol_pool)
  1435.             other_symbol_pool = new ConvertibleArray<Symbol *>(256);
  1436.         other_symbol_pool -> Next() = symbol;
  1437.     }
  1438.  
  1439.     SymbolTable(int hash_size_ = DEFAULT_HASH_SIZE);
  1440.     ~SymbolTable();
  1441.  
  1442.     inline void CompressSpace()
  1443.     {
  1444.         if (anonymous_symbol_pool)
  1445.             (void) anonymous_symbol_pool -> Array();
  1446.         if (method_symbol_pool)
  1447.             (void) method_symbol_pool -> Array();
  1448.         if (variable_symbol_pool)
  1449.             (void) variable_symbol_pool -> Array();
  1450.         if (other_symbol_pool)
  1451.             (void) other_symbol_pool -> Array();
  1452.  
  1453.         return;
  1454.     }
  1455.  
  1456. private:
  1457.  
  1458.     Tuple<TypeSymbol *> *type_symbol_pool; // This array should not be convertible. See SymbolTable::DeleteTypeSymbol
  1459.  
  1460.     ConvertibleArray<TypeSymbol *>     *anonymous_symbol_pool;
  1461.     ConvertibleArray<MethodSymbol *>   *method_symbol_pool;
  1462.     ConvertibleArray<VariableSymbol *> *variable_symbol_pool;
  1463.     ConvertibleArray<Symbol *>         *other_symbol_pool;
  1464.  
  1465.     Symbol **base;
  1466.     int hash_size;
  1467.  
  1468.     static int primes[];
  1469.     int prime_index;
  1470.  
  1471.     int Size()
  1472.     {
  1473.         return NumAnonymousSymbols() +
  1474.                NumTypeSymbols() +
  1475.                NumMethodSymbols() +
  1476.                NumVariableSymbols() +
  1477.                NumOtherSymbols();
  1478.     }
  1479.     void Rehash();
  1480.  
  1481.     MethodSymbol *constructor;
  1482.  
  1483. public:
  1484.  
  1485.     inline PathSymbol *InsertPathSymbol(NameSymbol *, DirectorySymbol *);
  1486.     inline PathSymbol *FindPathSymbol(NameSymbol *);
  1487.     inline DirectorySymbol *InsertDirectorySymbol(NameSymbol *, Symbol *);
  1488.     inline DirectorySymbol *FindDirectorySymbol(NameSymbol *);
  1489.     inline FileSymbol *InsertFileSymbol(NameSymbol *);
  1490.     inline FileSymbol *FindFileSymbol(NameSymbol *);
  1491.     inline PackageSymbol *InsertPackageSymbol(NameSymbol *, PackageSymbol *);
  1492.     inline PackageSymbol *FindPackageSymbol(NameSymbol *);
  1493.     inline TypeSymbol *InsertAnonymousTypeSymbol(NameSymbol *);
  1494.     inline TypeSymbol *InsertSystemTypeSymbol(NameSymbol *);
  1495.     inline TypeSymbol *InsertOuterTypeSymbol(NameSymbol *);
  1496.     inline TypeSymbol *InsertNestedTypeSymbol(NameSymbol *);
  1497.     inline void DeleteTypeSymbol(TypeSymbol *);
  1498.     inline void DeleteAnonymousTypes();
  1499.     inline TypeSymbol *FindTypeSymbol(NameSymbol *);
  1500.     inline MethodSymbol *InsertMethodSymbol(NameSymbol *);
  1501.     inline MethodSymbol *InsertConstructorSymbol(NameSymbol *);
  1502.     inline void InsertMethodSymbol(MethodSymbol *);
  1503.     inline void InsertConstructorSymbol(MethodSymbol *);
  1504.     inline MethodSymbol *FindMethodSymbol(NameSymbol *);
  1505.     inline MethodSymbol *FindConstructorSymbol();
  1506.     inline VariableSymbol *InsertVariableSymbol(NameSymbol *);
  1507.     inline void InsertVariableSymbol(VariableSymbol *);
  1508.     inline VariableSymbol *FindVariableSymbol(NameSymbol *);
  1509.     inline LabelSymbol *InsertLabelSymbol(NameSymbol *);
  1510.     inline LabelSymbol *FindLabelSymbol(NameSymbol *);
  1511.     inline BlockSymbol *InsertBlockSymbol(int);
  1512.  
  1513.     inline MethodSymbol *Overload(MethodSymbol *);
  1514.     inline void Overload(MethodSymbol *, MethodSymbol *);
  1515.     inline MethodSymbol *LocalConstructorOverload(MethodSymbol *);
  1516.     MethodSymbol *FindOverloadMethod(MethodSymbol *, AstMethodDeclarator *);
  1517. };
  1518.  
  1519.  
  1520. inline int TypeSymbol::NumVariableSymbols() { return (table ? table -> NumVariableSymbols() : 0); }
  1521. inline VariableSymbol *TypeSymbol::VariableSym(int i) { return table -> VariableSym(i); }
  1522.  
  1523. inline int BlockSymbol::NumVariableSymbols() { return (table ? table -> NumVariableSymbols() : 0); }
  1524. inline VariableSymbol *BlockSymbol::VariableSym(int i) { return table -> VariableSym(i); }
  1525.  
  1526. inline int TypeSymbol::NumMethodSymbols() { return (table ? table -> NumMethodSymbols() : 0); }
  1527. inline MethodSymbol *TypeSymbol::MethodSym(int i) { return table -> MethodSym(i); }
  1528.  
  1529. inline int TypeSymbol::NumTypeSymbols() { return (table ? table -> NumTypeSymbols() : 0); }
  1530. inline TypeSymbol *TypeSymbol::TypeSym(int i) { return table -> TypeSym(i); }
  1531.  
  1532. inline void TypeSymbol::CompressSpace() { if (table) table -> CompressSpace(); }
  1533. inline void BlockSymbol::CompressSpace() { if (table) table -> CompressSpace(); }
  1534.  
  1535. inline PathSymbol *SymbolTable::InsertPathSymbol(NameSymbol *name_symbol, DirectorySymbol *directory_symbol)
  1536. {
  1537.     assert(base);
  1538.  
  1539.     PathSymbol *symbol = new PathSymbol(name_symbol);
  1540.     directory_symbol -> owner = symbol;
  1541.     symbol -> root_directory = directory_symbol;
  1542.     AddOtherSymbol(symbol);
  1543.  
  1544.     int k = name_symbol -> index % hash_size;
  1545.     symbol -> next = base[k];
  1546.     base[k] = symbol;
  1547.  
  1548.     //
  1549.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1550.     // 2 times the size of the base, and we have not yet reached the maximum
  1551.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1552.     //
  1553.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1554.         Rehash();
  1555.  
  1556.     return symbol;
  1557. }
  1558.  
  1559.  
  1560. inline PathSymbol *SymbolTable::FindPathSymbol(NameSymbol *name_symbol)
  1561. {
  1562.     assert(base);
  1563.  
  1564.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1565.     {
  1566.         if (name_symbol == symbol -> Identity())
  1567.             return (PathSymbol *) symbol;
  1568.     }
  1569.  
  1570.     return (PathSymbol *) NULL;
  1571. }
  1572.  
  1573.  
  1574. inline DirectorySymbol *SymbolTable::InsertDirectorySymbol(NameSymbol *name_symbol, Symbol *owner)
  1575. {
  1576.     assert(base);
  1577.  
  1578.     DirectorySymbol *symbol = new DirectorySymbol(name_symbol, owner);
  1579.     AddOtherSymbol(symbol);
  1580.  
  1581.     int k = name_symbol -> index % hash_size;
  1582.     symbol -> next = base[k];
  1583.     base[k] = symbol;
  1584.  
  1585.     //
  1586.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1587.     // 2 times the size of the base, and we have not yet reached the maximum
  1588.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1589.     //
  1590.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1591.         Rehash();
  1592.  
  1593.     return symbol;
  1594. }
  1595.  
  1596.  
  1597. inline DirectorySymbol *DirectorySymbol::InsertDirectorySymbol(NameSymbol *name_symbol)
  1598. {
  1599.     DirectorySymbol *subdirectory_symbol = Table() -> InsertDirectorySymbol(name_symbol, this);
  1600.     this -> subdirectories.Next() = subdirectory_symbol;
  1601.  
  1602.     return subdirectory_symbol;
  1603. }
  1604.  
  1605.  
  1606. inline DirectorySymbol *SymbolTable::FindDirectorySymbol(NameSymbol *name_symbol)
  1607. {
  1608.     assert(base);
  1609.  
  1610.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1611.     {
  1612.         if (name_symbol == symbol -> Identity())
  1613.         {
  1614.             DirectorySymbol *directory_symbol = symbol -> DirectoryCast();
  1615.             if (directory_symbol)
  1616.                 return directory_symbol;
  1617.         }
  1618.     }
  1619.  
  1620.     return (DirectorySymbol *) NULL;
  1621. }
  1622.  
  1623.  
  1624. inline DirectorySymbol *DirectorySymbol::FindDirectorySymbol(NameSymbol *name_symbol)
  1625. {
  1626.     return (table ? table -> FindDirectorySymbol(name_symbol) : (DirectorySymbol *) NULL);
  1627. }
  1628.  
  1629.  
  1630. inline FileSymbol *SymbolTable::InsertFileSymbol(NameSymbol *name_symbol)
  1631. {
  1632.     assert(base);
  1633.  
  1634.     FileSymbol *symbol = new FileSymbol(name_symbol);
  1635.     AddOtherSymbol(symbol);
  1636.  
  1637.     int k = name_symbol -> index % hash_size;
  1638.     symbol -> next = base[k];
  1639.     base[k] = symbol;
  1640.  
  1641.     //
  1642.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1643.     // 2 times the size of the base, and we have not yet reached the maximum
  1644.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1645.     //
  1646.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1647.         Rehash();
  1648.  
  1649.     return symbol;
  1650. }
  1651.  
  1652.  
  1653. inline FileSymbol *DirectorySymbol::InsertFileSymbol(NameSymbol *name_symbol)
  1654. {
  1655.     return Table() -> InsertFileSymbol(name_symbol);
  1656. }
  1657.  
  1658.  
  1659. inline FileSymbol *SymbolTable::FindFileSymbol(NameSymbol *name_symbol)
  1660. {
  1661.     assert(base);
  1662.  
  1663.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1664.     {
  1665.         if (name_symbol == symbol -> Identity())
  1666.         {
  1667.             FileSymbol *file_symbol = symbol -> FileCast();
  1668.             if (file_symbol)
  1669.                 return file_symbol;
  1670.         }
  1671.     }
  1672.  
  1673.     return (FileSymbol *) NULL;
  1674. }
  1675.  
  1676.  
  1677. inline FileSymbol *DirectorySymbol::FindFileSymbol(NameSymbol *name_symbol)
  1678. {
  1679.     return (table ? table -> FindFileSymbol(name_symbol) : (FileSymbol *) NULL);
  1680. }
  1681.  
  1682.  
  1683. inline PackageSymbol *SymbolTable::InsertPackageSymbol(NameSymbol *name_symbol, PackageSymbol *owner)
  1684. {
  1685.     assert(base);
  1686.  
  1687.     PackageSymbol *symbol = new PackageSymbol(name_symbol, owner);
  1688.     AddOtherSymbol(symbol);
  1689.  
  1690.     int k = name_symbol -> index % hash_size;
  1691.     symbol -> next = base[k];
  1692.     base[k] = symbol;
  1693.  
  1694.     //
  1695.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1696.     // 2 times the size of the base, and we have not yet reached the maximum
  1697.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1698.     //
  1699.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1700.         Rehash();
  1701.  
  1702.     return symbol;
  1703. }
  1704.  
  1705.  
  1706. inline PackageSymbol *PackageSymbol::InsertPackageSymbol(NameSymbol *name_symbol)
  1707. {
  1708.     return Table() -> InsertPackageSymbol(name_symbol, this);
  1709. }
  1710.  
  1711.  
  1712. inline PackageSymbol *SymbolTable::FindPackageSymbol(NameSymbol *name_symbol)
  1713. {
  1714.     assert(base);
  1715.  
  1716.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1717.     {
  1718.         if (name_symbol == symbol -> Identity())
  1719.         {
  1720.             PackageSymbol *package_symbol = symbol -> PackageCast();
  1721.             if (package_symbol)
  1722.                 return package_symbol;
  1723.         }
  1724.     }
  1725.  
  1726.     return (PackageSymbol *) NULL;
  1727. }
  1728.  
  1729.  
  1730. inline PackageSymbol *PackageSymbol::FindPackageSymbol(NameSymbol *name_symbol)
  1731. {
  1732.   return (table ? table -> FindPackageSymbol(name_symbol) : (PackageSymbol *) NULL);
  1733. }
  1734.  
  1735. inline TypeSymbol *SymbolTable::InsertAnonymousTypeSymbol(NameSymbol *name_symbol)
  1736. {
  1737.     TypeSymbol *symbol = new TypeSymbol(name_symbol);
  1738.     AddAnonymousSymbol(symbol);
  1739.  
  1740.     return symbol;
  1741. }
  1742.  
  1743.  
  1744. inline TypeSymbol *TypeSymbol::InsertAnonymousTypeSymbol(NameSymbol *name_symbol)
  1745. {
  1746.     return Table() -> InsertAnonymousTypeSymbol(name_symbol);
  1747. }
  1748.  
  1749.  
  1750. inline TypeSymbol *SymbolTable::InsertSystemTypeSymbol(NameSymbol *name_symbol)
  1751. {
  1752.     assert(base);
  1753.  
  1754.     TypeSymbol *symbol = new TypeSymbol(name_symbol);
  1755.     symbol -> pool_index = NumTypeSymbols();
  1756.     AddTypeSymbol(symbol);
  1757.  
  1758.     int k = name_symbol -> index % hash_size;
  1759.     symbol -> next = base[k];
  1760.     base[k] = symbol;
  1761.  
  1762.     //
  1763.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1764.     // 2 times the size of the base, and we have not yet reached the maximum
  1765.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1766.     //
  1767.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1768.         Rehash();
  1769.  
  1770.     return symbol;
  1771. }
  1772.  
  1773.  
  1774. inline TypeSymbol *PackageSymbol::InsertSystemTypeSymbol(NameSymbol *name_symbol)
  1775. {
  1776.     return Table() -> InsertSystemTypeSymbol(name_symbol);
  1777. }
  1778.  
  1779.  
  1780. inline TypeSymbol *SymbolTable::InsertOuterTypeSymbol(NameSymbol *name_symbol)
  1781. {
  1782.     assert(base);
  1783.  
  1784.     TypeSymbol *symbol = new TypeSymbol(name_symbol);
  1785.     symbol -> pool_index = NumTypeSymbols();
  1786.     AddTypeSymbol(symbol);
  1787.  
  1788.     int k = name_symbol -> index % hash_size;
  1789.     symbol -> next = base[k];
  1790.     base[k] = symbol;
  1791.  
  1792.     //
  1793.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1794.     // 2 times the size of the base, and we have not yet reached the maximum
  1795.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1796.     //
  1797.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1798.         Rehash();
  1799.  
  1800.     return symbol;
  1801. }
  1802.  
  1803.  
  1804. inline TypeSymbol *PackageSymbol::InsertOuterTypeSymbol(NameSymbol *name_symbol)
  1805. {
  1806.     return Table() -> InsertOuterTypeSymbol(name_symbol);
  1807. }
  1808.  
  1809.  
  1810. inline TypeSymbol *SymbolTable::InsertNestedTypeSymbol(NameSymbol *name_symbol)
  1811. {
  1812.     assert(base);
  1813.  
  1814.     TypeSymbol *symbol = new TypeSymbol(name_symbol);
  1815.     symbol -> pool_index = NumTypeSymbols();
  1816.     AddTypeSymbol(symbol);
  1817.  
  1818.     int k = name_symbol -> index % hash_size;
  1819.     symbol -> next = base[k];
  1820.     base[k] = symbol;
  1821.  
  1822.     //
  1823.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1824.     // 2 times the size of the base, and we have not yet reached the maximum
  1825.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1826.     //
  1827.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1828.         Rehash();
  1829.  
  1830.     return symbol;
  1831. }
  1832.  
  1833.  
  1834. inline TypeSymbol *TypeSymbol::InsertNestedTypeSymbol(NameSymbol *name_symbol)
  1835. {
  1836.     return Table() -> InsertNestedTypeSymbol(name_symbol);
  1837. }
  1838.  
  1839.  
  1840. inline void SymbolTable::DeleteTypeSymbol(TypeSymbol *type)
  1841. {
  1842.     assert(base);
  1843.  
  1844.     int k = type -> name_symbol -> index % hash_size;
  1845.     if (type == base[k])
  1846.         base[k] = type -> next;
  1847.     else
  1848.     {
  1849.         Symbol *previous = base[k];
  1850.         for (Symbol *symbol = previous -> next; symbol != type; previous = symbol, symbol = symbol -> next)
  1851.             ;
  1852.         previous -> next = type -> next;
  1853.     }
  1854.  
  1855.     int last_index = NumTypeSymbols() - 1;
  1856.     if (type -> pool_index != last_index)
  1857.     {// move last element to position previously occupied by element being deleted
  1858.         TypeSym(last_index) -> pool_index = type -> pool_index;
  1859.         TypeSym(type -> pool_index) = TypeSym(last_index);
  1860.     }
  1861.  
  1862.     type_symbol_pool -> Reset(last_index); // remove last slot in symbol_pool
  1863.  
  1864.     delete type;
  1865.  
  1866.     return;
  1867. }
  1868.  
  1869.  
  1870. inline void PackageSymbol::DeleteTypeSymbol(TypeSymbol *type)
  1871. {
  1872.     if (table)
  1873.         table -> DeleteTypeSymbol(type);
  1874. }
  1875.  
  1876.  
  1877. inline void SymbolTable::DeleteAnonymousTypes()
  1878. {
  1879.     for (int i = 0; i < NumAnonymousSymbols(); i++)
  1880.         delete AnonymousSym(i);
  1881.     delete anonymous_symbol_pool;
  1882.     anonymous_symbol_pool = NULL;
  1883.  
  1884.     return;
  1885. }
  1886.  
  1887.  
  1888. inline void TypeSymbol::DeleteAnonymousTypes()
  1889. {
  1890.     delete anonymous_types;
  1891.     anonymous_types = NULL;
  1892.     if (table)
  1893.         table -> DeleteAnonymousTypes();
  1894. }
  1895.  
  1896. inline TypeSymbol *SymbolTable::FindTypeSymbol(NameSymbol *name_symbol)
  1897. {
  1898.     assert(base);
  1899.  
  1900.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  1901.     {
  1902.         if (name_symbol == symbol -> Identity())
  1903.         {
  1904.             TypeSymbol *type = symbol -> TypeCast();
  1905.             if (type)
  1906.                 return type;
  1907.         }
  1908.     }
  1909.  
  1910.     return (TypeSymbol *) NULL;
  1911. }
  1912.  
  1913.  
  1914. inline TypeSymbol *PackageSymbol::FindTypeSymbol(NameSymbol *name_symbol)
  1915. {
  1916.     return (table ? table -> FindTypeSymbol(name_symbol) : (TypeSymbol *) NULL);
  1917. }
  1918.  
  1919.  
  1920. inline TypeSymbol *TypeSymbol::FindTypeSymbol(NameSymbol *name_symbol)
  1921. {
  1922.     return (table ? table -> FindTypeSymbol(name_symbol) : (TypeSymbol *) NULL);
  1923. }
  1924.  
  1925.  
  1926. inline MethodSymbol *SymbolTable::InsertMethodSymbol(NameSymbol *name_symbol)
  1927. {
  1928.     assert(base);
  1929.  
  1930.     MethodSymbol *symbol = new MethodSymbol(name_symbol);
  1931.     AddMethodSymbol(symbol);
  1932.  
  1933.     int k = name_symbol -> index % hash_size;
  1934.     symbol -> next = base[k];
  1935.     base[k] = symbol;
  1936.  
  1937.     //
  1938.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1939.     // 2 times the size of the base, and we have not yet reached the maximum
  1940.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1941.     //
  1942.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1943.         Rehash();
  1944.  
  1945.     return symbol;
  1946. }
  1947.  
  1948.  
  1949. inline MethodSymbol *TypeSymbol::InsertMethodSymbol(NameSymbol *name_symbol)
  1950. {
  1951.     return Table() -> InsertMethodSymbol(name_symbol);
  1952. }
  1953.  
  1954.  
  1955. inline MethodSymbol *SymbolTable::InsertConstructorSymbol(NameSymbol *name_symbol)
  1956. {
  1957.     assert(! constructor);
  1958.  
  1959.     this -> constructor = InsertMethodSymbol(name_symbol);
  1960.     return this -> constructor;
  1961. }
  1962.  
  1963.  
  1964. inline MethodSymbol *TypeSymbol::InsertConstructorSymbol(NameSymbol *name_symbol)
  1965. {
  1966.     return Table() -> InsertConstructorSymbol(name_symbol);
  1967. }
  1968.  
  1969.  
  1970. inline void SymbolTable::InsertMethodSymbol(MethodSymbol *method_symbol)
  1971. {
  1972.     assert(base);
  1973.  
  1974.     AddMethodSymbol(method_symbol);
  1975.  
  1976.     int k = method_symbol -> name_symbol -> index % hash_size;
  1977.     method_symbol -> next = base[k];
  1978.     base[k] = method_symbol;
  1979.  
  1980.     //
  1981.     // If the set is "adjustable" and the number of unique elements in it exceeds
  1982.     // 2 times the size of the base, and we have not yet reached the maximum
  1983.     // allowable size for a base, reallocate a larger base and rehash the elements.
  1984.     //
  1985.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1986.         Rehash();
  1987.  
  1988.     return;
  1989. }
  1990.  
  1991.  
  1992. inline void TypeSymbol::InsertMethodSymbol(MethodSymbol *method_symbol)
  1993. {
  1994.     Table() -> InsertMethodSymbol(method_symbol);
  1995. }
  1996.  
  1997.  
  1998. inline void SymbolTable::InsertConstructorSymbol(MethodSymbol *method_symbol)
  1999. {
  2000.     assert(! constructor);
  2001.  
  2002.     this -> constructor = method_symbol;
  2003.     InsertMethodSymbol(method_symbol);
  2004. }
  2005.  
  2006.  
  2007. inline void TypeSymbol::InsertConstructorSymbol(MethodSymbol *method_symbol)
  2008. {
  2009.     Table() -> InsertConstructorSymbol(method_symbol);
  2010. }
  2011.  
  2012.  
  2013. inline MethodSymbol *SymbolTable::FindMethodSymbol(NameSymbol *name_symbol)
  2014. {
  2015.     assert(base);
  2016.  
  2017.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  2018.     {
  2019.         if (name_symbol == symbol -> Identity())
  2020.         {
  2021.             MethodSymbol *method = symbol -> MethodCast();
  2022.             if (method)
  2023.                 return method;
  2024.         }
  2025.     }
  2026.  
  2027.     return (MethodSymbol *) NULL;
  2028. }
  2029.  
  2030.  
  2031. inline MethodSymbol *TypeSymbol::FindMethodSymbol(NameSymbol *name_symbol)
  2032. {
  2033.     return (table ? table -> FindMethodSymbol(name_symbol) : (MethodSymbol *) NULL);
  2034. }
  2035.  
  2036.  
  2037. inline MethodSymbol *SymbolTable::FindConstructorSymbol()
  2038. {
  2039.     return this -> constructor;
  2040. }
  2041.  
  2042. inline MethodSymbol *TypeSymbol::FindConstructorSymbol()
  2043. {
  2044.     return (table ? table -> FindConstructorSymbol() : (MethodSymbol *) NULL);
  2045. }
  2046.  
  2047. inline VariableSymbol *SymbolTable::InsertVariableSymbol(NameSymbol *name_symbol)
  2048. {
  2049.     assert(base);
  2050.  
  2051.     VariableSymbol *symbol = new VariableSymbol(name_symbol);
  2052.     AddVariableSymbol(symbol);
  2053.  
  2054.     int k = name_symbol -> index % hash_size;
  2055.     symbol -> next = base[k];
  2056.     base[k] = symbol;
  2057.  
  2058.     //
  2059.     // If the set is "adjustable" and the number of unique elements in it exceeds
  2060.     // 2 times the size of the base, and we have not yet reached the maximum
  2061.     // allowable size for a base, reallocate a larger base and rehash the elements.
  2062.     //
  2063.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  2064.         Rehash();
  2065.  
  2066.     return symbol;
  2067. }
  2068.  
  2069.  
  2070. inline VariableSymbol *TypeSymbol::InsertVariableSymbol(NameSymbol *name_symbol)
  2071. {
  2072.     return Table() -> InsertVariableSymbol(name_symbol);
  2073. }
  2074.  
  2075.  
  2076. inline VariableSymbol *BlockSymbol::InsertVariableSymbol(NameSymbol *name_symbol)
  2077. {
  2078.     return Table() -> InsertVariableSymbol(name_symbol);
  2079. }
  2080.  
  2081.  
  2082. inline void SymbolTable::InsertVariableSymbol(VariableSymbol *variable_symbol)
  2083. {
  2084.     assert(base);
  2085.  
  2086.     AddVariableSymbol(variable_symbol);
  2087.  
  2088.     int k = variable_symbol -> name_symbol -> index % hash_size;
  2089.     variable_symbol -> next = base[k];
  2090.     base[k] = variable_symbol;
  2091.  
  2092.     //
  2093.     // If the set is "adjustable" and the number of unique elements in it exceeds
  2094.     // 2 times the size of the base, and we have not yet reached the maximum
  2095.     // allowable size for a base, reallocate a larger base and rehash the elements.
  2096.     //
  2097.     if ((Size() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  2098.         Rehash();
  2099.  
  2100.     return;
  2101. }
  2102.  
  2103.  
  2104. inline void TypeSymbol::InsertVariableSymbol(VariableSymbol *variable_symbol)
  2105. {
  2106.     Table() -> InsertVariableSymbol(variable_symbol);
  2107. }
  2108.  
  2109.  
  2110. inline void BlockSymbol::InsertVariableSymbol(VariableSymbol *variable_symbol)
  2111. {
  2112.     Table() -> InsertVariableSymbol(variable_symbol);
  2113. }
  2114.  
  2115.  
  2116. inline VariableSymbol *SymbolTable::FindVariableSymbol(NameSymbol *name_symbol)
  2117. {
  2118.     assert(base);
  2119.  
  2120.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  2121.     {
  2122.         if (name_symbol == symbol -> Identity())
  2123.         {
  2124.             VariableSymbol *variable_symbol = symbol -> VariableCast();
  2125.             if (variable_symbol)
  2126.                 return variable_symbol;
  2127.         }
  2128.     }
  2129.  
  2130.     return (VariableSymbol *) NULL;
  2131. }
  2132.  
  2133.  
  2134. inline VariableSymbol *TypeSymbol::FindVariableSymbol(NameSymbol *name_symbol)
  2135. {
  2136.     return (table ? table -> FindVariableSymbol(name_symbol) : (VariableSymbol *) NULL);
  2137. }
  2138.  
  2139.  
  2140. inline VariableSymbol *BlockSymbol::FindVariableSymbol(NameSymbol *name_symbol)
  2141. {
  2142.     return (table ? table -> FindVariableSymbol(name_symbol) : (VariableSymbol *) NULL);
  2143. }
  2144.  
  2145.  
  2146. inline LabelSymbol *SymbolTable::InsertLabelSymbol(NameSymbol *name_symbol)
  2147. {
  2148.     assert(base);
  2149.  
  2150.     LabelSymbol *symbol = new LabelSymbol(name_symbol);
  2151.     AddOtherSymbol(symbol);
  2152.  
  2153.     int k = name_symbol -> index % hash_size;
  2154.     symbol -> next = base[k];
  2155.     base[k] = symbol;
  2156.  
  2157.     //
  2158.     // as only one label can be inserted in any given symboltable,
  2159.     // we don't need to try to rehash here !
  2160.     //
  2161.  
  2162.     return symbol;
  2163. }
  2164.  
  2165.  
  2166. inline LabelSymbol *SymbolTable::FindLabelSymbol(NameSymbol *name_symbol)
  2167. {
  2168.     assert(base);
  2169.  
  2170.     for (Symbol *symbol = base[name_symbol -> index % hash_size]; symbol; symbol = symbol -> next)
  2171.     {
  2172.         if (name_symbol == symbol -> Identity())
  2173.         {
  2174.             LabelSymbol *label = symbol -> LabelCast();
  2175.             if (label)
  2176.                 return label;
  2177.         }
  2178.     }
  2179.  
  2180.     return (LabelSymbol *) NULL;
  2181. }
  2182.  
  2183. inline BlockSymbol *SymbolTable::InsertBlockSymbol(int hash_size = 0)
  2184. {
  2185.     BlockSymbol *symbol = new BlockSymbol(hash_size);
  2186.     AddOtherSymbol(symbol);
  2187.  
  2188.     return symbol;
  2189. }
  2190.  
  2191.  
  2192. inline BlockSymbol *BlockSymbol::InsertBlockSymbol(int hash_size = 0)
  2193. {
  2194.     return Table() -> InsertBlockSymbol(hash_size);
  2195. }
  2196.  
  2197.  
  2198. inline MethodSymbol *SymbolTable::Overload(MethodSymbol *base_method)
  2199. {
  2200.     MethodSymbol *overload = new MethodSymbol(base_method -> Identity());
  2201.     AddMethodSymbol(overload);
  2202.  
  2203.     overload -> next = overload; // mark overloaded method
  2204.     overload -> next_method = base_method -> next_method;
  2205.     base_method -> next_method = overload;
  2206.  
  2207.     return overload;
  2208. }
  2209.  
  2210.  
  2211. inline MethodSymbol *TypeSymbol::Overload(MethodSymbol *base_method)
  2212. {
  2213.     assert(table);
  2214.  
  2215.     return table -> Overload(base_method);
  2216. }
  2217.  
  2218.  
  2219. inline void SymbolTable::Overload(MethodSymbol *base_method, MethodSymbol *overload)
  2220. {
  2221.     AddMethodSymbol(overload);
  2222.  
  2223.     overload -> next = overload; // mark overloaded method
  2224.     overload -> next_method = base_method -> next_method;
  2225.     base_method -> next_method = overload;
  2226.  
  2227.     return;
  2228. }
  2229.  
  2230. inline void TypeSymbol::Overload(MethodSymbol *base_method, MethodSymbol *overload)
  2231. {
  2232.     assert(table);
  2233.  
  2234.     table -> Overload(base_method, overload);
  2235. }
  2236.  
  2237.  
  2238. inline MethodSymbol *SymbolTable::LocalConstructorOverload(MethodSymbol *base_method)
  2239. {
  2240.     MethodSymbol *overload = new MethodSymbol(base_method -> Identity());
  2241.     AddMethodSymbol(overload);
  2242.  
  2243.     overload -> next = overload; // mark overloaded method
  2244.     overload -> SetGeneratedLocalConstructor(base_method);
  2245.  
  2246.     return overload;
  2247. }
  2248.  
  2249.  
  2250. inline MethodSymbol *TypeSymbol::LocalConstructorOverload(MethodSymbol *base_method)
  2251. {
  2252.     assert(table);
  2253.  
  2254.     return table -> LocalConstructorOverload(base_method);
  2255. }
  2256.  
  2257.  
  2258. inline MethodSymbol *TypeSymbol::FindOverloadMethod(MethodSymbol *base_method, AstMethodDeclarator *method_declarator)
  2259. {
  2260.     return (table ? table -> FindOverloadMethod(base_method, method_declarator) : (MethodSymbol *) NULL);
  2261. }
  2262.  
  2263.  
  2264. inline SymbolTable *DirectorySymbol::Table()
  2265. {
  2266.     return (table ? table : table = new SymbolTable(101));
  2267. }
  2268.  
  2269. inline SymbolTable *PackageSymbol::Table()
  2270. {
  2271.     return (table ? table : table = new SymbolTable(101));
  2272. }
  2273.  
  2274. inline void TypeSymbol::SetSymbolTable(int estimate)
  2275. {
  2276.     if (! table) // If table was not yet allocated, allocate one based on the estimate
  2277.         table = new SymbolTable(estimate);
  2278. }
  2279.  
  2280. inline SymbolTable *TypeSymbol::Table()
  2281. {
  2282.     return (table ? table : table = new SymbolTable());
  2283. }
  2284.  
  2285. inline SymbolTable *BlockSymbol::Table()
  2286. {
  2287.     return (table ? table : table = new SymbolTable());
  2288. }
  2289.  
  2290. #ifdef UNIX_FILE_SYSTEM
  2291.     inline bool FileSymbol::IsClassSuffix(char *suffix)
  2292.     {
  2293.         return (strncmp(suffix, class_suffix, class_suffix_length) == 0);
  2294.     }
  2295.  
  2296.     inline bool  FileSymbol::IsJavaSuffix(char *suffix)
  2297.     {
  2298.         return (strncmp(suffix, java_suffix, java_suffix_length) == 0);
  2299.     }
  2300. #elif defined(WIN32_FILE_SYSTEM)
  2301.     inline bool FileSymbol::IsClassSuffix(char *suffix)
  2302.     {
  2303.         return Case::StringSegmentEqual(suffix, class_suffix, class_suffix_length);
  2304.     }
  2305.  
  2306.     inline bool  FileSymbol::IsJavaSuffix(char *suffix)
  2307.     {
  2308.         return Case::StringSegmentEqual(suffix, java_suffix, java_suffix_length);
  2309.     }
  2310. #elif defined(AMIGAOS_FILE_SYSTEM)
  2311.     // Do not use StringSegmentEqual() as in the WIN32 case, because that
  2312.     // function may check beyond the end of the string, thus possibly causing
  2313.     // enforcer hits.
  2314.     inline bool FileSymbol::IsClassSuffix(char *suffix)
  2315.     {
  2316.         return (strncasecmp(suffix, class_suffix, class_suffix_length) == 0);
  2317.     }
  2318.  
  2319.     inline bool  FileSymbol::IsJavaSuffix(char *suffix)
  2320.     {
  2321.         return (strncasecmp(suffix, java_suffix, java_suffix_length) == 0);
  2322.     }
  2323. #endif
  2324.  
  2325. #endif // ifndef symbol_INCLUDED
  2326.